CONVENT.TXT FEB-01-88 PROGRAMMING CONVENTIONS The importance of adopting and sticking to conventions cannot be overstated. Assembly language programming needs to be restricted. This is the main idea behind structured programming. Assembly language programming is like sculpting a blob of clay. What is needed are some basic structures like the integrated circuit industry have developed. Indeed, the integrated circuit industry has advanced far faster the the software industry. High level languages are a powerful tool for reducing software costs. Computer commands can be specified in a succinct and consistent manner. Collections of general purpose, easy-to-understand, routines (libraries) are the key factor in reducing software costs. Realize that exceptions to the following rules will cause confusion, and that now-a-days, the most important priority in programming is usually to minimize confusion. The traditional concerns about memory consumption and speed-of- execution are diminishing. Code which does not follow these conventions cannot be tolerated even if it works. It must be modified to conform to these conventions. It is interesting to note that it was more difficult to modify Peter's code, in the case of BYTEIO, than it was to rewrite it completely from scratch as in the case of CONHAN. ASSEMBLY LANGUAGE CODE Only resort to assembly language if XPL cannot be used for some reason. Subroutines must preserve the contents of registers or list the bombed registers as part of the description of what the routine does. Contrary to many 68000 programmer's conventions, there is no such thing as scratch registers which do not have to be preserved across subroutine calls. Subroutines should have one entry point and one exit point. (The use of the 'RETURN' statement in XPL should be avoided except for returning values at the end of a function.) Subroutine entry points are given global names which are distinct from internal line number names, which have numeric suffixes. Use BSR and BRA to refer to locations within a module; use JSR and JMP to refer to locations outside a module. This will help make the module relocatable and costs nothing. (Use PC relative addressing when referring to data within the module.) Keep all variables together and at the beginning of a module. ASSEMBLY LANGUAGE DATA In addition to the rules for structured programming there need to be some rules for data manipulation. The 68000 is much more register oriented than the 6502. It is efficient for a routine to load up the registers with variables and start crunching. Input and output variables (arguments) can be passed in the registers. A significant difference between the 6502 and the 68000 is the convention on byte order. The 6502 has the least significant byte first, while the 68000 has the most significant byte first. 68000 code should not use 6502 conventions, and vice versa. ARGUMENTS Arguments (subroutine input and output variables) can be passed in registers, on the stack or in global variables. Using global variables is the least desirable way. If they are used they must be clearly commented as inputs or outputs. It should be impossible (or at least difficult) to blow up an XPL program. Hence all variables which originate with XPL code, such as device numbers, should be checked for validity before they are used. Currently, function codes do not originate in XPL code and consequently do not need to be checked (although the code will surely blow if they're wrong). When a value in a register is returned from a subroutine, the entire long word is assumed to be correct even if only the lower byte is used. (The high bytes are zero in this case). A single boolean argument should be passed in a data register. (Note that most operations -- even MOVE -- clear the C and Z bits, and there is no branch on X.) A boolean value may be returned in the same manner. Pure booleans should be used. That is, 'FALSE' = $00000000 and 'TRUE' = $FFFFFFFF. (Note that NOT.L of $FF is not necessarily equal to $00000000, it might be equal to $FFFFFF00. BUFFERS FIFO buffers will always be implemented the same way. The first location of the buffer will always be the name of the buffer. The last location + 1 will always be used as the end. (This location will be clearly distinguished from the acutal end which is the last location.) The address registers (An) will be used to directly access the contents, that is, indexing off the base address will not be used (except in multi-dimensional arrays where the index is the same for several sub-arrays). The "A" register will always point to the next location to be processed. If you are filling a FIFO then the "A" register will always point to an empty location. If you are emptying a FIFO then the "A" register will always point to the location about to be emptied. The pointer will always be incremented. APEX DIRECTORY STRUCTURE The jumbled order of the Apex directories will cause a tremendous amount of confusion in the future. This must be weighed against the value of maintaining compatible directories between 6502 and 68000 systems (which is quite useful when using XDUP). The 6502 systems are not going to be replaced overnight; it will take years. A certain amount of data will be exchanged between the two systems. Right now there is a very crude RS-232 link. It is expected that Iomegas will be common to both systems. A directory conversion routine could be used. The major conflicts are the reversed order of the bytes in 16-bit values, and the separate, extended directory caused by the Apple RWTS boot. Conversion routines should be used. DAMN LINE FEEDS Line feeds are a classic example of what happens when conventions clash. Line feeds are trivial, but they have caused an unbelievable amount of trouble. Now, within the Apex software environment there is no such thing as a line feed . There is only a carriage return , which means advance to the beginning of the next line. The hardware environment is different. To hardware, a means move to the start of the current line, and a means move down one line. It is the purpose of the device handler to cause a from the software to move the hardware to the start of the next line by whatever means is required. NAMES Variable names should be nouns; procedure names should be verbs. Descriptive adjectives should be added at the end, not at the beginning as is natural with English. Variables Procedures LINE COUNT ERROR3 DELETE ERROR_FATAL DRAWLINE Use plural nouns to stand for the number of something; use singular nouns for array names (parenthesis make arrays obvious). NAME \Array of names NAMES \Total number of elements in NAME NAMEMIN \The minimum subscript (usually = 0) NAMEMAX \The maximum subscript (usually = NAMES -1) MISCELLANY Don't underestimate the difficulty of designing an effective human interface. The simple scrolling technique has many subtle advantages over a paging technique. Avoid using form feeds which erase useful information. It is amazing how often they are used to immediately erase an error message before it can be read. Use defensive programming. Whenever a comparison for equality is made it usually costs nothing to, for example, test for greater than or equal in case the greater than situation ever arrises. When using the 68000, the data type "word" is to be avoided. XPL does not recognize it, it usually is not a significant saving in place of a long word, and it simplifies things to eliminate it altogether. Distinguish between a pointer and an index. A pointer contains an absolute address, while an index is added to a base address to get the desired absolute address. "Index" is another name for "subscript". PROGRAMMERS VS. PEOPLE People always count one, two, three..., but the intelligent programmer isn't sure whether to start with one or zero. Distinguish between the programmer's world and the people world. Have a very good reason if you change a convention. ero. Distinguish between the programmer's world and the people world. Have a very good reaso